#==============================================================================
#  _   _                         ____                _             
# | | | | ___  _ __ ___   ___   / ___|___  _ __ ___ (_)_ __   __ _ 
# | |_| |/ _ \| '_ ` _ \ / _ \ | |   / _ \| '_ ` _ \| | '_ \ / _` |
# |  _  | (_) | | | | | |  __/ | |__| (_) | | | | | | | | | | (_| |
# |_| |_|\___/|_| |_| |_|\___|  \____\___/|_| |_| |_|_|_| |_|\__, |
#                                                            |___/ 
#------------------------------------------------------------------------------
# Project:	Home Coming / 2D platform
# Author:	zx.longgi
# Time:		08/10-2010 
# Usage:	A level data holder
# Description:	hold level data
# ClassName:	zlevel
#==============================================================================


#Development notes:
#1. this class will only have one instance in the game

import os.path
import os

from zfile_concrete import zfile_concrete
from zblock import zblock_simple
from zobject_static import zobject_static

class zlevel_simple(zfile_concrete):
	"""First attempt of level data storage"""
	#map properties
	map_levelname = ""
	map_background_colour = []
	map_concrete_version = ""
	map_world_builder = ""
	map_commadlines = ""
	
	#[Note:denied]the low level static object may not be needed eventually
	#[Note]Low lvl static object list is more useful than store everything
	#	in blocks
	#list_zst_object = [[1,"name1", <instance>],[2, "name2", <inst>]]
	list_zst_object = []
	list_blocks_idx_version = []
	
	#blocks, this is list of zblock_simple instances.
	list_blocks = []
	
	def __init__(self, levelname):
		self.map_levelname = levelname
		self.open_concrete_file_and_read()
		self.lets_read_map_properties()
		self.lets_make_blocks()
	
	def open_concrete_file_and_read(self):
		#based on levelname prepare filename
		filename = os.path.join(os.getcwd(), self.map_levelname + \
			".concrete")
		self.open_and_prepare_concrete_file(filename)
	
	#----------------------------------------------------------------------
	def lets_read_map_properties(self):
		"""read map properties into level data structure"""
		for each_property in self.map_property_list:
			if(each_property[0] == "back_ground_colour"):
				self.map_background_colour = \
				self.read_plain_int_list(each_property[1])
			if(each_property[0] == "ConcreteVersion"):
				self.map_background_colour = \
				float(each_property[1])
			if(each_property[0] == "WorldBuilder"):
				self.map_background_colour = \
				self.remove_quotation_marks(each_property[1])
			if(each_property[0] == "CommandLine"):
				self.map_background_colour = \
				self.remove_quotation_marks(each_property[1])
	
	#----------------------------------------------------------------------
	def lets_make_blocks(self):
		"""list all zobject static 1st ,put idx into block instance"""
		#deal with static object list
		for each_so_line in self.static_object_list:
			temp_zso_instance_box = \
			self.make_a_zobject_static_instance(each_so_line)
			self.list_zst_object.add(temp_zso_instance_box)
			
		#deal with block list (idx version):
		for each_bk_line in self.block_list:
			temp_blk_instance_box = \
			self.make_a_block_instance(each_bk_line)
			self.list_blocks_idx_version.add(temp_blk_instance_box)
	
	#----------------------------------------------------------------------
	def make_a_block_instance(self, bk_line):
		"""input is a list about blocks info, return a instance"""
		# build a returning instance
		rt_block = zblock_simple()
		
		#read the idx list
		temp_idx_list = self.read_plain_int_list(bk_line[0])
		rt_block.zobject_static_idx_list = temp_idx_list
		
		#read base position
		temp_bpos = self.read_base_postion(bk_line[1])
		rt_block.base_position = temp_bpos
		
		#read if blocking
		temp_blocking = self.read_boolean_value(bk_line[2])
		rt_block.is_blocking = temp_blocking
		
		return rt_block
	
	#----------------------------------------------------------------------
	def make_a_zobject_static_instance(self, so_line):
		"""input is a list about static object, return a instance"""
		# build a potential returning instance of zobject_static
		rt_zso = zobject_static()
		# build a retuning list of [idx, "name", <instance>]
		rt_lst = [0, "", rt_zso]
		
		#read index
		temp_index = int(so_line[0])
		#read name
		temp_name = self.remove_quotation_marks(so_line[1])
		
		# put into rt_list
		rt_list[0] = temp_index
		rt_list[1] = temp_name
		
		#read z index 
		temp_zindex = int(so_line[2])
		rt_list[2].z_level = temp_zindex
		
		#read base position
		temp_bpos = self.read_base_postion(so_line[3])
		rt_list[2].base_position = temp_bpos
		
		#read shape
		temp_shape = int(so_line[4])
		rt_list[2].vertice_count = temp_shape
		
		#read vertex list
		temp_vlist = self.read_position_list(so_line[5])
		rt_list[2].vertex_list = temp_vlist
		
		#read if use texture
		temp_usetex = self.read_boolean_value(so_line[6])
		rt_list[2].is_use_texture = temp_usetex
		
		#read texture place string
		temp_texplace = self.remove_quotation_marks(so_line[7])
		rt_list[2].tex_resource = temp_texplace
		
		#read texture coordinates
		temp_texcoord = self.read_position_list(so_line[8])
		rt_list[2].texcoord_list = temp_texcoord
		
		#read proper colour
		temp_colour = self.read_plain_int_list(so_line[9])
		rt_list[2].proper_colour = temp_colour
		
		#read visibility
		temp_visibility = self.read_boolean_value(so_line[10])
		rt_list[2].is_visible = temp_visibility
		
		return rt_list
	
	#----------------------------------------------------------------------
	def lets_make_blocks_non_static_object_version_need_2b_removed(self):
		"""go through all blocks in low level storage"""
		#if block list or static object list is empty, return false
		if(len(block_list) == 0 or len(static_object_list) == 0):
			return False
			
		for each_lblock in block_list:
			#create a new block
			new_block = zblock_simple()
			#find base position of this block
			base_pos = self.read_base_postion(each_lblock[1])
			if(base_pos == False):
				return False
			new_block.base_position = base_pos
			
			#find blocking
			if(int(each_lblock[2]) == 1):
				new_block.is_blocking = True
			else:
				new_block.is_blocking = False
			
			#find how many static object in this block
			idx_list = self.read_plain_int_list(each_lblock[0])
			if(idx_list == False):
				return False
			if(len(idx_list) == 0):
				return False
			
			#start circulation for each static object
			for idx in idx_list:
				#prepare
				sobj = static_object_list[idx-1]
				temp_zobj = zobject_static()
				
				#name string
				temp_zobj.name_string = sobj[0]
				
				#z-index
				temp_zobj.z_level = int(sobj[1])
				
				#find base position of this static object
				base_pos = self.read_base_postion(sobj[2])
				if(base_pos == False):
					return False
				temp_zobj.base_position = base_pos
				
				#find shape
				temp_zobj.vertice_count = int(sobj[3])
				
				#find vertices list
				zvertex_list = self.read_position_list(sobj[4])
				if(zvertex_list == False):
					return False
				temp_zobj.vertex_list = zvertex_list
				
				#find if use texture
				zobj_usetex = int(sobj[5])
				if(zobj_usetex == 1):
					temp_zobj.is_use_texture = True
				else:
					temp_zobj.is_use_texture = False
				
				#texture detial
				if(temp_zobj.is_use_texture):
					temp_zobj.tex_resource = ""
					temp_zobj.texcoord_list = []
				else:
					temp_zobj.tex_resource = ""
					temp_zobj.texcoord_list = []
				
				#find colour
				colour_list = \
					self.read_plain_int_list(each_lblock[8])
				if(colour_list == False):
					return False
				if(len(colour_list) == 0):
					temp_zobj.proper_colour = \
						[255,255,255,255]
				else:
					temp_zobj.proper_colour = colour_list
				
				#find visibility
				zobj_visibility = int(sobj[9])
				if(zobj_visibility == 1):
					temp_zobj.is_visible = True
				else:
					temp_zobj.is_visible = False
			
				new_block.static_object_list.add(temp_zobj)
				new_block.static_object_count++
				
			list_blocks.add(new_block)
			
			
	#----------------------------------------------------------------------
	def remove_square_bracket(self, strin):
		"""remove square brackets from input string"""
		strin = strin.strip()
		#less than 3 characters
		if(len(strin)<=2):
			return False
		
		if(strin[0] == '[' and strin[-1] == ']'):
			strout = strin[1:len(strin)-2]
			return strout
		else:
			return False
	
	def remove_quotation_marks(self, strin):
		"""remove square brackets from input string"""
		strin = strin.strip()
		#less than 3 characters
		if(len(strin)<=2):
			return False
		
		if(strin[0] == '"' and strin[-1] == '"'):
			strout = strin[1:len(strin)-2]
			return strout
		else:
			return False
			
	def read_boolean_value(self, strin):
		"""read boolean value, other == False, 1 == True"""
		if(int(strin) == 1):
			return True
		else:
			return False
	
	def read_base_postion(self, strpos):
		"""read base postion string, return in list or false"""
		#remove square brackets
		strpos = self.remove_square_bracket(strpos)
		if(strpos != False):
			#split string by ,
			temp_pos_list = strpos.split(',')
			if(len(temp_pos_list) == 2):
				temp_pos_list[0] = float(temp_pos_list[0])
				temp_pos_list[1] = float(temp_pos_list[1])
				
				return temp_pos_list
			else:
				return False
		else:
			return False
			
	def read_plain_int_list(self, strpos):
		"""read base postion string, return in list or false"""
		#remove square brackets
		strpos = self.remove_square_bracket(strpos)
		if(strpos != False):
			#split string by ,
			temp_pos_list = strpos.split(',')
			for i in range(len(temp_pos_list)):
				temp_pos_list[i] = int(temp_pos_list[i])
				
			return temp_pos_list
		else:
			return False
			
	def read_position_list(self, strin):
		"""read position list"""
		#remove square brackets
		strin = self.remove_square_bracket(strin)
		if(strin != False):
			#split string by ;
			temp_pos_list = strin.split(';')
			tempo_pos_list = []
			for each_pos in temp_pos_list:
				templ_each_pos = each_pos.split(',')
				if(len(templ_each_pos) == 2):
					templ_each_pos[0] = \
						float(templ_each_pos[0])
					templ_each_pos[1] = \
						float(templ_each_pos[1])
					
					tempo_pos_list.add(templ_each_pos)
				else:
					return False
			return tempo_pos_list
		else:
			return False